package org.langcom;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class TimeUtils {

	private static final String SPACE = " "; //$NON-NLS-1$
	private static final String SEMICOLON = ":"; //$NON-NLS-1$
	public static final long MILLIS_PER_SECOND = 1000;
	public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
	public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
	public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;
	public static final long MILLIS_PER_WEEK = 7 * MILLIS_PER_DAY;
	public static final long MILLIS_PER_MONTH = 31 * MILLIS_PER_DAY;
	public static final long MILLIS_PER_YEAR = 12 * MILLIS_PER_MONTH;
	private static final String NN = ""; //$NON-NLS-1$
	private static final String DD = ":"; //$NON-NLS-1$
	private static final String NOLL = "0"; //$NON-NLS-1$

	public static boolean afterByDays(Date one, Date two) {
		Calendar oneCal = getCalendar(one);
		resetTime(oneCal);
		Calendar twoCal = getCalendar(two);
		resetTime(twoCal);
		return oneCal.after(twoCal);
	}

	public static boolean beforeByDays(Date one, Date two) {
		Calendar oneCal = getCalendar(one);
		resetTime(oneCal);
		Calendar twoCal = getCalendar(two);
		resetTime(twoCal);
		return oneCal.before(twoCal);
	}

	public static Calendar rewindTime(Calendar previousTime, int timeUnit, int units) {
		final Calendar changedDateCalendar = Calendar.getInstance();
		changedDateCalendar.setTimeInMillis(previousTime.getTime().getTime());
		changedDateCalendar.add(timeUnit, units);
		return changedDateCalendar;
	}

	/*
	 * public static Date rewindDate(Date baseDate, int timeUnit, int units) { if(timeUnit != Calendar.DAY_OF_YEAR || timeUnit != Calendar.MONTH) { throw new UnsupportedOperationException("Other time
	 * units not supported yet!"); } switch (timeUnit) { case Calendar.DAY_OF_YEAR: return new Date(baseDate.getTime() + (long) units * DateUtils.MILLIS_IN_DAY); } }
	 */
	public static int getCompleteDaysCount(Date dd) {
		Date localDate = shiftRelativeUTC(dd);
		return (int) ((localDate.getTime() - (localDate.getTime() % MILLIS_PER_DAY)) / MILLIS_PER_DAY);
	}

	private static Date shiftRelativeUTC(Date dd) {
		Calendar sDate = Calendar.getInstance();
		sDate.setTime(dd);
		sDate.add(Calendar.MILLISECOND, TimeZone.getDefault().getRawOffset());
		return sDate.getTime();
	}

	public static int daysBetween(Date from, Date to) {
		return getCompleteDaysCount(to) - getCompleteDaysCount(from);
	}

	public static Date addDays(int days, Date date) {
		return new Date(date.getTime() + (long) days * MILLIS_PER_DAY);
	}

	public static Calendar getCalendar(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	public static void resetTime(Calendar calendar) {
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(Calendar.HOUR, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
	}

	public static String getHoursMinutes(float hours) {
		String result = ""; //$NON-NLS-1$
		BigDecimal decimal = new BigDecimal(hours);
		result = decimal.intValue() + SPACE + SEMICOLON + SPACE + decimal.subtract(new BigDecimal(decimal.intValue())).multiply(new BigDecimal(60)).intValue();
		return result;
	}

	public static String getHoursMinutesLabels(float hours) {
		String result = ""; //$NON-NLS-1$
		BigDecimal decimal = new BigDecimal(hours);
		result = decimal.intValue() + SPACE + Messages.TimeUtils_0 + SPACE + SPACE
			+ decimal.subtract(new BigDecimal(decimal.intValue())).multiply(new BigDecimal(60)).intValue() + SPACE + Messages.TimeUtils_1;
		return result;
	}

	public static String getStringHour(long time) {
		String result = ""; //$NON-NLS-1$
		long abs = Math.abs(time);
		long hours = (abs) / MILLIS_PER_HOUR;
		long minutes = (abs - hours * MILLIS_PER_HOUR) / MILLIS_PER_MINUTE;
		long seconds = (abs - hours * MILLIS_PER_HOUR - minutes * MILLIS_PER_MINUTE) / MILLIS_PER_SECOND;
		result = (hours > 0 && hours < 23 ? hours : "00") //$NON-NLS-1$
			+ SEMICOLON + (minutes > 0 ? (minutes < 10 ? "0" : "") + minutes : "00") //$NON-NLS-1$
			+ SEMICOLON + (seconds > 0 ? (seconds < 10 ? "0" : "") + seconds : "00"); //$NON-NLS-1$
		return result;
	}

	public static String between(long fromTime, long toTime) {
		return formatdate(Math.abs(toTime - fromTime));
	}

	public static boolean inside(Date fromDate, Date date, Date todate) {
		if (fromDate.getTime() < date.getTime()) {
			if (todate.getTime() > date.getTime()) {
				return true;
			}
		}
		return false;
	}

	public static String formatdate(Long time) {
		if (time == null || time == 0) {
			return NN;
		}
		long ptime = Math.abs(time);
		long days = ptime / MILLIS_PER_DAY;
		long hours = (ptime - days * MILLIS_PER_DAY) / MILLIS_PER_HOUR;
		long minutes = (ptime - days * MILLIS_PER_DAY - hours * MILLIS_PER_HOUR) / MILLIS_PER_MINUTE;
		long seconds = (ptime - days * MILLIS_PER_DAY - hours * MILLIS_PER_HOUR - minutes * MILLIS_PER_MINUTE) / MILLIS_PER_SECOND;
		StringBuilder builder = new StringBuilder();
		if (days > 0 && days < 365) {
			builder.append(days);
			builder.append(" d "); //$NON-NLS-1$
		}
		builder.append(hours < 10 ? NOLL : NN);
		builder.append(hours);
		builder.append(DD);
		builder.append(minutes < 10 ? NOLL : NN);
		builder.append(minutes);
		builder.append(DD);
		builder.append(seconds < 10 ? NOLL : NN);
		builder.append(seconds);
		return builder.toString();
	}
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd  kk:mm"); //$NON-NLS-1$

	public static String formatdate2(Long time) {
		if (time == 0) {
			return ""; //$NON-NLS-1$
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(time);
		return format.format(calendar.getTime()).trim();
	}
}
